home *** CD-ROM | disk | FTP | other *** search
- // Entropy collection utilities
- /*
- In information theory, entropy is a measure of the uncertainty associated
- with a random variable. The term by itself in this context usually refers
- to the Shannon entropy, which quantifies, in the sense of an expected
- value, the information contained in a message, usually in units such as
- bits. Equivalently, the Shannon entropy is a measure of the average
- information content one is missing when one does not know the value of the
- random variable. The concept was introduced by Claude E. Shannon in his
- 1948 paper "A Mathematical Theory of Communication".
-
- Shannon's entropy represents an absolute limit on the best possible
- lossless compression of any communication, under certain constraints:
- treating messages to be encoded as a sequence of independent and
- identically-distributed random variables, Shannon's source coding theorem
- shows that, in the limit, the average length of the shortest possible
- representation to encode the messages in a given alphabet is their entropy
- divided by the logarithm of the number of symbols in the target alphabet.
-
- A fair coin has an entropy of one bit. However, if the coin is not fair,
- then the uncertainty is lower (if asked to bet on the next outcome, we
- would bet preferentially on the most frequent result), and thus the Shannon
- entropy is lower. Mathematically, a coin flip is an example of a Bernoulli
- trial, and its entropy is given by the binary entropy function. A long
- string of repeating characters has an entropy rate of 0, since every
- character is predictable. The entropy rate of English text is between 1.0
- and 1.5 bits per letter,[1] or as low as 0.6 to 1.3 bits per letter,
- according to estimates by Shannon based on human experiments.
- From: http://en.wikipedia.org/wiki/Entropy_(information_theory)
- */
-
- /* Start by declaring static storage and initialise
- the entropy vector from the time we come through
- here. */
-
- var entropyData = new Array(); // Collected entropy data
- var edlen = 0; // Keyboard array data length
-
- addEntropyTime(); // Start entropy collection with page load time
- ce(); // Roll milliseconds into initial entropy
-
- // Add a byte to the entropy vector
-
- function addEntropyByte(b) {
- entropyData[edlen++] = b;
- }
-
- /* Capture entropy. When the user presses a key or performs
- various other events for which we can request
- notification, add the time in 255ths of a second to the
- entropyData array. The name of the function is short
- so it doesn't bloat the form object declarations in
- which it appears in various "onXXX" events. */
-
- function ce() {
- addEntropyByte(Math.floor((((new Date).getMilliseconds()) * 255) / 999));
- }
-
- // Add a 32 bit quantity to the entropy vector
-
- function addEntropy32(w) {
- var i;
-
- for (i = 0; i < 4; i++) {
- addEntropyByte(w & 0xFF);
- w >>= 8;
- }
- }
-
- /* Add the current time and date (milliseconds since the epoch,
- truncated to 32 bits) to the entropy vector. */
-
- function addEntropyTime() {
- addEntropy32((new Date()).getTime());
- }
-
- /* Start collection of entropy from mouse movements. The
- argument specifies the number of entropy items to be
- obtained from mouse motion, after which mouse motion
- will be ignored. Note that you can re-enable mouse
- motion collection at any time if not already underway. */
-
- var mouseMotionCollect = 0;
- var oldMoveHandler; // For saving and restoring mouse move handler in IE4
-
- function mouseMotionEntropy(maxsamp) {
- if (mouseMotionCollect <= 0) {
- mouseMotionCollect = maxsamp;
- if ((document.implementation.hasFeature("Events", "2.0")) &&
- document.addEventListener) {
- // Browser supports Document Object Model (DOM) 2 events
- document.addEventListener("mousemove", mouseMoveEntropy, false);
- } else {
- if (document.attachEvent) {
- // Internet Explorer 5 and above event model
- document.attachEvent("onmousemove", mouseMoveEntropy);
- } else {
- // Internet Explorer 4 event model
- oldMoveHandler = document.onmousemove;
- document.onmousemove = mouseMoveEntropy;
- }
- }
- //dump("Mouse enable", mouseMotionCollect);
- }
- }
-
- /* Collect entropy from mouse motion events. Note that
- this is craftily coded to work with either DOM2 or Internet
- Explorer style events. Note that we don't use every successive
- mouse movement event. Instead, we XOR the three bytes collected
- from the mouse and use that to determine how many subsequent
- mouse movements we ignore before capturing the next one. */
-
- var mouseEntropyTime = 0; // Delay counter for mouse entropy collection
-
- function mouseMoveEntropy(e) {
- if (!e) {
- e = window.event; // Internet Explorer event model
- }
- if (mouseMotionCollect > 0) {
- if (mouseEntropyTime-- <= 0) {
- addEntropyByte(e.screenX & 0xFF);
- addEntropyByte(e.screenY & 0xFF);
- ce();
- mouseMotionCollect--;
- mouseEntropyTime = (entropyData[edlen - 3] ^ entropyData[edlen - 2] ^
- entropyData[edlen - 1]) % 19;
- //dump("Mouse Move", byteArrayToHex(entropyData.slice(-3)));
- }
- if (mouseMotionCollect <= 0) {
- if (document.removeEventListener) {
- document.removeEventListener("mousemove", mouseMoveEntropy, false);
- } else if (document.detachEvent) {
- document.detachEvent("onmousemove", mouseMoveEntropy);
- } else {
- document.onmousemove = oldMoveHandler;
- }
- //dump("Spung!", 0);
- }
- }
- }
-
- /* Compute a 32 byte key value from the entropy vector.
- We compute the value by taking the MD5 sum of the even
- and odd bytes respectively of the entropy vector, then
- concatenating the two MD5 sums. */
-
- function keyFromEntropy() {
- var i, k = new Array(32);
-
- if (edlen == 0) {
- alert(strBundle.getFormattedString("entropyErrMessage", [ "keyFromEntropy" ]));
- }
- //dump("Entropy bytes", edlen);
-
- md5_init();
- for (i = 0; i < edlen; i += 2) {
- md5_update(entropyData[i]);
- }
- md5_finish();
- for (i = 0; i < 16; i++) {
- k[i] = digestBits[i];
- }
-
- md5_init();
- for (i = 1; i < edlen; i += 2) {
- md5_update(entropyData[i]);
- }
- md5_finish();
- for (i = 0; i < 16; i++) {
- k[i + 16] = digestBits[i];
- }
-
- //dump("keyFromEntropy", byteArrayToHex(k));
- return k;
- }
-